//
//  YLActionSheetView.swift
//  Swift-Codedase
//
//  Created by xyanl on 2024/4/11.
//  Copyright © 2024 考拉🐨. All rights reserved.
//

import UIKit
import Reusable
import Localize_Swift

class YLActionSheetView: UIView {
    
    /// 显示 ActionSheet
    /// - Parameters:
    ///   - titleItems: items 列表
    ///   - cancelItem: 取消 item
    ///   - headerView: headerView
    ///   - selectHandler: 被选中 item 触发事件，index 是 item 在当前列表中的位置，获取指定某个 item 需要设置 tag
    ///   - cancelHandler: 取消触发事件
    static func show(
        _ titleItems: [YLActionSheetItem],
        cancelItem: YLActionSheetItem? = nil,
        headerView: UIView? = nil,
        selectHandler: ((YLActionSheetItem, Int) -> Void)?,
        cancelHandler: (() -> Void)? = nil
    ) {
        let view = YLActionSheetView(frame: UIScreen.main.bounds)
        view.tableHeaderView = headerView
        view.cancelItem = cancelItem ?? defaultCancelItem()
        view.selectHandler = selectHandler
        view.cancelHandler = cancelHandler
        view.items = titleItems
        view.changeColor()
        xKeyWindow.addSubview(view)
        view.showView()
    }
    
    /// 显示 ActionSheet
    /// - Parameters:
    ///   - titles: title 列表
    ///   - cancelTitle: 取消 item 的 title
    ///   - headerView: headerView
    ///   - selectHandler: 被选中 item 触发事件，index 是 item 在当前列表中的位置，获取指定某个 item 需要设置 tag
    ///   - cancelHandler: 取消触发事件
    static func show(
        _ titles: [String],
        cancelTitle: String? = nil,
        headerView: UIView? = nil,
        selectHandler: ((YLActionSheetItem, Int) -> Void)?,
        cancelHandler: (() -> Void)? = nil
    ) {
        let view = YLActionSheetView(frame: UIScreen.main.bounds)
        view.tableHeaderView = headerView
        
        if cancelTitle == nil {
            view.cancelItem = defaultCancelItem()
        } else {
            view.cancelItem = YLActionSheetItem(title: cancelTitle!)
        }
        
        view.selectHandler = selectHandler
        view.cancelHandler = cancelHandler
        var items: [YLActionSheetItem] = []
        titles.forEach { title in
            items.append(YLActionSheetItem(title: title))
        }
        view.items = items
        view.changeColor()
        xKeyWindow.addSubview(view)
        view.showView()
    }
    
    private var selectHandler: ((YLActionSheetItem, Int) -> Void)?
    private var cancelHandler: (() -> Void)?
    
    private var items: [YLActionSheetItem] = [] {
        didSet {
            tableView.reloadData()
            changeColor()
            recalculateHeight()
        }
    }
    
    /// 自定义headerView
    /// 如果单独设置tableViewHeaderView，设置之后需要调用 recalculateHeight 方法重新计算高度
    private var tableHeaderView: UIView? {
        didSet {
            guard let view = tableHeaderView else { return }
            tableView.tableHeaderView = view
        }
    }
    
    /// 取消按钮文案
    private var cancelItem: YLActionSheetItem! {
        didSet {
            cancelButton.setTitle(cancelItem.title.localized(), for: .normal)
            cancelButton.titleLabel?.font = cancelItem.titleFont
        }
    }
    /// 默认取消按钮
    static private func defaultCancelItem() -> YLActionSheetItem {
        return YLActionSheetItem(title: "取消")
    }
    
    /// 是否自适应暗黑模式
    private var adaptiveDarkness: Bool = true {
        didSet {
            changeColor()
            tableView.reloadData()
        }
    }
    
    
    // 懒加载
    private lazy var tableView: UITableView = {
        let tableView = UITableView(frame: CGRectMake(0, 0, width, 0), style: .plain)
        tableView.delegate = self
        tableView.dataSource = self
        tableView.isScrollEnabled = false
        tableView.backgroundColor = .white
        tableView.separatorStyle = .none
        if #available(iOS 15.0, *) {
            tableView.sectionHeaderTopPadding = 0
        }
        tableView.register(cellType: YLActionSheetViewCell.self)
        return tableView
    }()
    
    private lazy var bgView: UIView = {
        let view = UIView(frame: bounds)
        view.isUserInteractionEnabled = true
        view.addGestureRecognizer(UITapGestureRecognizer.init(target: self, action: #selector(hideView)))
        view.backgroundColor = .black.setAlpha(0.5)
        return view
    }()
    
    private lazy var contentView: UIView = {
        let view = UIView(frame: CGRectMake(0, 0, bounds.width, 0))
        view.backgroundColor = UIColor(hex: "#F7F7F7")
        view.addSubview(tableView)
        view.addSubview(footerCancelView)
        
        return view
    }()
    
    private lazy var footerCancelView: UIView = {
        let view = UIView(frame: CGRectMake(0, 0, bounds.width, 60 + xIphoneBottomSafeHeight))
        view.backgroundColor = .white
        view.isUserInteractionEnabled = true
        view.addGestureRecognizer(UITapGestureRecognizer.init(target: self, action: #selector(hideView)))
        view.addSubview(cancelButton)
        return view
    }()
    
    private lazy var cancelButton: UIButton = {
        let button = UIButton.init(type: .custom)
        button.frame = CGRectMake(0, 0, bounds.width, 60 + xIphoneBottomSafeHeight)
        button.setTitle("取消", for: .normal)
        button.setTitleColor(UIColor(hex: "#333333"), for: .normal)
        button.titleLabel?.font = UIFont.systemFont(ofSize: 17, weight: .medium)
        button.backgroundColor = .clear
        button.addTarget(self, action: #selector(didCancelBtnClick), for: .touchUpInside)
        button.titleEdgeInsets = UIEdgeInsets(top: -xIphoneBottomSafeHeight, left: 0, bottom: 0, right: 0)
        return button
    }()
    
    /// 显示完成
    private var showViewCompletion: Bool = false
    private var contentViewHeight: CGFloat = 0
    private var tableViewHeight: CGFloat = 0
    
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        addSubview(bgView)
        addSubview(contentView)
        contentView.addRoundedCorners(corner: [.topLeft, .topRight], cornerRadius: 10)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    @objc private func hideView() {
        showViewCompletion = false
        UIView.animate(withDuration: 0.25) { [self] in
            bgView.alpha = 0.0
            contentView.top = height
        } completion: { [self] finished in
            removeFromSuperview()
        }
    }
    
    private func showView() {
        bgView.alpha = 0.0
        contentView.top = height
        
        UIView.animate(withDuration: 0.25) { [self] in
            bgView.alpha = 1.0
            contentView.top = height - contentView.height
        } completion: { [self] finished in
            showViewCompletion = true
        }
    }
    
    private func resetContentViewFrame() {
        if contentView.top != height - contentViewHeight {
            if !showViewCompletion {
                bgView.alpha = 0.0
                contentView.top = height
            }
            
            UIView.animate(withDuration: 0.25) { [self] in
                bgView.alpha = 1.0
                contentView.top = height - contentViewHeight
                contentView.height = contentViewHeight
                tableView.height = tableViewHeight
                footerCancelView.top = CGRectGetMaxY(tableView.frame) + 8.0
            } completion: { [self] finished in
                showViewCompletion = true
            }
        }
    }
    
    private func recalculateHeight() {
        var totalHeight = (tableView.tableHeaderView?.height ?? 0.0) + (tableView.tableFooterView?.height ?? 0.0)
        
        var canScrollHeight: CGFloat = 0
        
        for (i, item) in items.enumerated() {
            // 所有cell 的高度
            totalHeight = totalHeight + item.rowHeight
            if i <= 4 {
                // 最多可滑动的只有4行
                canScrollHeight = canScrollHeight + item.rowHeight
            }
        }
        
        if totalHeight > height - canScrollHeight - xIphoneBottomSafeHeight {
            totalHeight = height - canScrollHeight - xIphoneBottomSafeHeight
            // 超出最大高度,可以滑动
            tableView.isScrollEnabled = true
        }
        
        tableView.top = 0
        tableView.height = totalHeight
        tableViewHeight = totalHeight
        
        footerCancelView.top = CGRectGetMaxY(tableView.frame) + 8.0
        contentView.height = CGRectGetMaxY(footerCancelView.frame)
        contentViewHeight = contentView.height
        tableView.reloadData()
        
        resetContentViewFrame()
        
        contentView.addRoundedCorners(corner: [.topLeft, .topRight], cornerRadius: 10)
        //tableView.addRoundedCorners(corner: [.topLeft, .topRight], cornerRadius: 10)
        
    }
    
    @objc private func didCancelBtnClick(sender: UIButton) {
        cancelHandler?()
        hideView()
    }
    
    private func changeColor() {
        let isDark = adaptiveDarkness ? Global.isDark : false
        
        bgView.backgroundColor = isDark ? UIColor(hex: "#141414").setAlpha(0.5): .black.setAlpha(0.5)
        
        contentView.backgroundColor = isDark ? UIColor(hex: "#1E1E1E"): UIColor(hex: "#F7F7F7")
        
        tableView.backgroundColor = isDark ? UIColor(hex: "#2D2D2D"): .white
        
        footerCancelView.backgroundColor = isDark ? UIColor(hex: "#2D2D2D"): .white
        
        if cancelItem != nil {
            cancelButton.setTitleColor(isDark ? cancelItem.titleDarkColor: cancelItem.titleColor, for: .normal)
            if cancelButton.isHighlighted {
                cancelButton.backgroundColor = isDark ? .white: UIColor(hex: "#E5E5E5")
            } else {
                cancelButton.backgroundColor = .clear
            }
        }
        
    }
    
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)
        
        if traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
            changeColor()
        }
        
    }
}

extension YLActionSheetView: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        items.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(for: indexPath, cellType: YLActionSheetViewCell.self)
        
        let item = items[indexPath.row]
        if item.isCanSelect {
            cell.selectionStyle = .default
        } else {
            cell.selectionStyle = .none
        }
        
        cell.item = item
        cell.isHideLine = indexPath.row == (items.count - 1)
        
        return cell
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        let item = items[indexPath.row]
        return item.rowHeight
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: false)
        let item = items[indexPath.row]
        if !item.isCanSelect {
            return
        }
        
        selectHandler?(item, indexPath.row)
        hideView()
        
    }
    
}
